﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Diagnostics;

namespace GoogleAnalyticsSolution
{
    /// <summary>
    /// Put in the masterfile: <SharePoint:DelegateControl runat="server" ControlId="GoogleAnalytics" AllowMultipleControls="true"/>
    /// </summary>
    public class GoogleAnalyticsLoader : Control
    {

        public string GoogleAnalyticsUrl { get; set; }

        public string TrackerCode { get; set; }

        public bool TrackAuthenticated { get; set; }

        public bool TrackEditMode { get; set; }

        private static string GATC_PREFIX = "GoogleAnalyticsTrackerCode_";

        public static string GetRecursiveWebStringProperty(SPSite site, SPWeb startweb, SPUrlZone zone, bool recurse, string PropertyPrefix)
        {
            if (startweb == null) return null;
            if (site == null) return null;

            try
            {
                Guid webid = startweb.ID;
                while (!webid.Equals(Guid.Empty))
                {
                    using (SPWeb web = site.OpenWeb(webid))
                    {
                        if (web.AllProperties.ContainsKey(PropertyPrefix + zone.ToString()))
                        {
                            return (string)web.AllProperties[PropertyPrefix + zone.ToString()];
                        }

                        if (recurse)
                        {
                            webid = web.ParentWebId;
                        }
                        else webid = Guid.Empty;
                    }
                }
            }
            catch (Exception ex)
            {
                SPSecurity.RunWithElevatedPrivileges(delegate
                {
                    EventLog.WriteEntry("GoogleAnalyticsLoader", ex.ToString(), EventLogEntryType.Warning);
                });
            }

            return null;
        }

        /// <summary>
        /// Gets the TrackerCode from the web or from the parentwebs if it's inherited.
        /// </summary>
        /// <param name="web"></param>
        /// <returns>A trackercode, null if no trackercode found, empty when trackercode was disabled</returns>
        public static string GetTrackerCode(SPSite site, SPWeb web, SPUrlZone zone, bool recurse)
        {
            return GetRecursiveWebStringProperty(site, web, zone, recurse, GATC_PREFIX);
        }

        private static string GATEM_PREFIX = "GoogleAnalyticsTrackEditMode_";

        public static bool? GetTrackEditMode(SPSite site, SPWeb web, SPUrlZone zone, bool recurse)
        {
            bool b;
            if (bool.TryParse(GetRecursiveWebStringProperty(site, web, zone, recurse, GATEM_PREFIX), out b))
            {
                return b;
            }
            return null;
        }

        private static string GATTA_PREFIX = "GoogleAnalyticsTrackAuthenticated_";

        public static bool? GetTrackAuthenticated(SPSite site, SPWeb web, SPUrlZone zone, bool recurse)
        {
            bool b;
            if (bool.TryParse(GetRecursiveWebStringProperty(site, web, zone, recurse, GATTA_PREFIX), out b))
            {
                return b;
            }
            return null;
        }

        public static void SetTrackerCode(SPWeb web, SPUrlZone zone, string code)
        {
            if (code == null)
            {
                web.AllProperties.Remove("GoogleAnalyticsTrackerCode_" + zone.ToString());
            }
            else
            {
                web.AllProperties["GoogleAnalyticsTrackerCode_" + zone.ToString()] = code;
            }
        }

        public static void SetTrackAuthenticated(SPWeb web, SPUrlZone zone, bool? value)
        {
            if (value.HasValue)
            {
                web.AllProperties["GoogleAnalyticsTrackAuthenticated_" + zone.ToString()] = value.Value.ToString();
            }
            else
            {
                web.AllProperties.Remove("GoogleAnalyticsTrackAuthenticated_" + zone.ToString());
            }
        }

        public static void SetTrackEditMode(SPWeb web, SPUrlZone zone, bool? value)
        {
            if (value.HasValue)
            {
                web.AllProperties["GoogleAnalyticsTrackEditMode_" + zone.ToString()] = value.Value.ToString();
            }
            else
            {
                web.AllProperties.Remove("GoogleAnalyticsTrackEditMode_" + zone.ToString());
            }
        }


        protected override void CreateChildControls()
        {
            try
            {
                string code = TrackerCode;
                bool editmode = TrackEditMode;
                bool authenticated = TrackAuthenticated;

                SPSite site = SPContext.Current.Site;
                SPWeb web = SPContext.Current.Web;

                if (site != null && web != null)
                {
                    bool? em = GetTrackEditMode(site, web, site.Zone, true);
                    if (em.HasValue)
                    {
                        editmode = em.Value;
                    }

                    bool? au = GetTrackAuthenticated(site, web, site.Zone, true);
                    if (au.HasValue)
                    {
                        authenticated = au.Value;
                    }

                    string pc = GetTrackerCode(site, web, site.Zone, true);

                    // Only use the found trackercode if it's disabled (empty string) or has a value.
                    if (pc != null) code = pc;

                }

                if (SPContext.Current.FormContext.FormMode != Microsoft.SharePoint.WebControls.SPControlMode.Display && !editmode)
                {
                    return;
                }

                if (web.CurrentUser != null && !authenticated)
                {
                    return;
                }

                if (!string.IsNullOrEmpty(code))
                {
                    Literal initscript = new Literal();
                    Controls.Add(initscript);
                    initscript.Text = string.Format("<script language=\"javascript\" type=\"text/javascript\">var gaJsHost = ((\"https:\" == document.location.protocol) ? \"https://ssl.\" : \"http://www.\");document.write(unescape(\"%3Cscript src='\" + gaJsHost + \"google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E\"));</script><script type=\"text/javascript\">try{{var pageTracker = _gat._getTracker(\"{0}\");pageTracker._trackPageview();}} catch(err) {{}}</script>", code);
                }
                base.CreateChildControls();
            }
            catch (Exception ex)
            {
                SPSecurity.RunWithElevatedPrivileges(delegate
                {
                    EventLog.WriteEntry(this.GetType().FullName, ex.ToString(), EventLogEntryType.Error);
                });
            }
        }
    }
}
